#include <jsonrpc/Icore.h>
#include "polarisdata/PolarisData.h"

/**
 * 饿汉式实现单例，在代码运行时就创建实例，保证线程安全
 * Hungry man style implementation of singleton, creating instances at code runtime to ensure thread safety
 */
Icore Icore::instance;

/**
 * @brief constructor, run only once when the singleton is created. Create new TestSram and ModbusSystem
 * 构造函数，仅在单例创建时运行一次，创建新的TestSram和ModbusSystem类
 */
Icore::Icore()
{
    sram = new TestSram(this);
    modbusSystem = new ModbusSystem(this);
}

Icore::~Icore()
{
    // TODO 自动生成的析构函数存根
}

/**
 * @brief only way to get instance of singleton Icore
 * 获取Icore单例的唯一方式
 * @return instance of Icore
 */
Icore &Icore::getInstance()
{
    return instance;
}

// UNUSED 未添加任何功能
int Icore::testSram(int num, int *result)
{
    return 0;
}

/**
 * @brief write to sram depending on num（根据num的值写对应的寄存器）
 * @param num 
 * @param result unused
 * @return always 0
 */
int Icore::printCmd(int num, int *result)
{
    switch (num)
    {
    case 0:
        sram->fsmc->writeReg(101, 0, 0);
        rt_thread_mdelay(1);
        sram->fsmc->writeReg(101, 0, 1);
        break;
    case 1:
        sram->fsmc->writeReg(100, 1, 0);
        break;
    case 2:
        sram->fsmc->writeReg(100, 1, 1);
        break;
    case 3:
        sram->fsmc->writeReg(100, 2, 0);
        break;
    case 4:
        sram->fsmc->writeReg(100, 2, 1);
        break;
    case 5:
        sram->fsmc->writeReg(101, 1, 0);
        rt_thread_mdelay(1);
        sram->fsmc->writeReg(101, 1, 1);
        break;
    case 6:
        sram->fsmc->writeReg(101, 15, 0);
        rt_thread_mdelay(1);

        for (int i = 0; i < 80000; i++)
        {
            sram->fsmc->writeReg(101, 0, 0);
            rt_thread_mdelay(1);
            sram->fsmc->writeReg(101, 0, 1);
            rt_thread_mdelay(1);
        }

        rt_thread_mdelay(1000);

        sram->fsmc->writeReg(101, 15, 1);
        rt_thread_mdelay(1);

        for (int i = 0; i < 80000; i++)
        {
            sram->fsmc->writeReg(101, 0, 0);
            rt_thread_mdelay(1);
            sram->fsmc->writeReg(101, 0, 1);
            rt_thread_mdelay(1);
        }
        break;

    default:
        break;
    }
    return 0;
}

/**
 * @brief write data to fsmc according to addr
 * （根据addr地址写对应的FSMC数据）
 * @param addr （地址）
 * @param data （数据）
 * @param result unused
 * @return always 0
 */
int Icore::printParam(int addr, int data, int *result)
{
    switch (addr)
    {
    case 105:
    case 107:
        sram->fsmc->writeFsmc(addr, (data & 0xFFFF));
        sram->fsmc->writeFsmc(addr + 1, ((data >> 16) & 0xFFFF));
        break;
    default:
        sram->fsmc->writeFsmc(addr, (data & 0xFFFF));
        break;
    }
    // rt_kprintf("addr %d , data %d\n",addr,data);
    return 0;
}

int Icore::printReset(int num)
{
    sram->fsmc->resetSram();
    sram->fsmc->writeReg(100, 2, 0);
    PolarisData::sdramData.reset();
    return 0;
}
